#include "tcpserver.h"
extern string sqlmsg;
void addsig(int sig,void(handler)(int),bool restart=true)
{
    struct sigaction sa;
    memset(&sa, '\0', sizeof(sa));
    sa.sa_handler = handler;
    if(restart)
    {
        sa.sa_flags |= SA_RESTART;
    }
    sigfillset(&sa.sa_mask);
    assert(sigaction(sig, &sa, NULL) != -1);
}

void show_error(int connfd,const char* info)
{
    printf("%s", info);
    send(connfd, info, strlen(info), 0);
    close(connfd);
}
tcpserver::tcpserver()
{
    m_user = "root";
    m_passwd = "zzc5201314";
    m_databasename = "myshare";
    m_users = new tcpconn[MAX_FD];
}
tcpserver::~tcpserver()
{
    close(m_epollfd);
    close(m_listenfd);
    delete [] m_users;
    delete m_threadpool;
}
void tcpserver::sqlpool_init()
{
    m_connpool=connection_pool::GetInstance();
    m_connpool->init("localhost", m_user, m_passwd, m_databasename, 3306, 8, 0);
    tcpconn::connpool=m_connpool;
}

void tcpserver::threadpool_init()
{

    m_threadpool = new threadpool<tcpconn>;
}

void tcpserver::event_listen()
{
    m_listenfd = socket(PF_INET, SOCK_STREAM, 0);
    assert(m_listenfd >= 0);
    struct linger tmp = {1, 0};
    setsockopt(m_listenfd, SOL_SOCKET, SO_LINGER, &tmp, sizeof(tmp));

    int ret = 0;
    struct sockaddr_in address;
    bzero(&address, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = htons(PORT);

    ret = bind(m_listenfd, (struct sockaddr *)&address, sizeof(address));
    assert(ret >= 0);

    ret = listen(m_listenfd, 5);
    assert(ret >= 0);
}

void tcpserver::epoll_run()
{
    epoll_event events[MAX_EVENT_NUMBER];
    m_epollfd = epoll_create(5);
    addfd(m_epollfd, m_listenfd, false);
    tcpconn::m_epollfd = m_epollfd;  //http_conn中的所有m_sockfd都有同一个epoll控制

    while(true)
    {
        int number = epoll_wait(m_epollfd, events, MAX_EVENT_NUMBER, -1);
        if((number<0)&&errno!=EINTR)
            {
                printf("epoll failure\n");
                break;
            }
		printf("epoll ok num= %d\n",number);
            for (int i = 0; i < number;i++)
            {

                int sockfd = events[i].data.fd;
                if (sockfd == m_listenfd)
                {
                    struct sockaddr_in client_address;
                    socklen_t client_addrlength = sizeof(client_address);
                    //每个套接字都对应分配好空间的http_conn对象
                    int connfd = accept(m_listenfd, (struct sockaddr *)&client_address, &client_addrlength);
                    if (connfd < 0)
                    {
                        printf("errno is: %s\n", errno);
                        continue;
                    }
                 /*   if(http_conn::m_user_count>=MAX_FD)
                    {
                        show_error(connfd, "Internal server busy");
                        continue;
                    }*/
                    m_users[connfd].init(connfd, client_address);
			printf("create a conn %d %s\n",connfd,&client_address);
                }
                else if (events[i].events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR))
                {
		printf("error to connect\n");
                    m_users[sockfd].close_conn();
                }
                else if (events[i].events & EPOLLIN)
                {
			printf("reading...\n");
                        m_threadpool->append(m_users + sockfd);
                }
                else if(events[i].events&EPOLLOUT)
                {
		printf("writting...");
                    m_users[sockfd].tcpwrite();
        }
                 else
                    {printf("unknow...\n");}
               printf("vvv\n");
            }
    }
}
